#include "main.h"
#define NUM_DIRECTIONS 8  
#define STAY_THRESHOLD 3   
#define LCD_WIDTH 84
#define LCD_HEIGHT 48
#define MAP_WIDTH 840   
#define MAP_HEIGHT 480  
#define POINT_WIDTH 18
#define POINT_HEIGHT 15
#define ROLE_W 24
#define ROLE_H 24
#define NPC_W 24
#define NPC_H 24
#define ENERGY_POINT_COUNT 256
#define HEART_POINT_COUNT 50


int direction_count[NUM_DIRECTIONS] = {0};
bool energy_point_collected[sizeof(energy_point_pos) / sizeof(energy_point_pos[0])] = {false};
uint16_t heart_point_pos[HEART_POINT_COUNT][2];
bool heart_collected[HEART_POINT_COUNT] = {false};

int last_direction = -1;
int point_num = sizeof(energy_point_pos) / sizeof(energy_point_pos[0]);

int role_x = 30;     
int role_y = 15;      
const int min_x = 20;
const int max_x = 40;
const int min_y = 10;
const int max_y = 20;
char facing_direction = 'R';
uint8_t screen_state=0, menu_index=0,setting_index=0,instruction_index=0,achievement_index=0;

uint8_t pos = 0;                        
const uint8_t BACKGROUND_WIDTH = 64;    

int cover_time = 200;
int screen_offset_x = 400; 
int screen_offset_y = 200;

uint8_t role_heat_flag=0;
uint8_t role_health = 4;

uint8_t level_up_flag = 0;

/**
 * Function to show the game screen.
 * This includes the cover screen if the game is loading, or the menu screen if screen_state is 0,
 * or the gameplay screen if screen_state is 1.
 */
void screen_show() 
{
    if (screen_slow) return;
    screen_slow = 1;

    ////////////////////// cover show
    if (cover_time >= 0)
    {
        cover_time--;
        lcd.clear();
        lcd.show_cover();
        draw_border();
        lcd.refresh();
        return;
    }
    //////////////////////
    if (screen_state == 0) {
        lcd.clear();
        lcd.printString("  Evo Battle", 0, 1);

        if (menu_index == 0) {
            lcd.printString("1. Start Game", 0, 2);
            lcd.invertLine(16);  
        } else {
            lcd.printString("1. Start Game", 0, 2);
        }

        if (menu_index == 1) { 
            lcd.printString("2. Settings", 0, 3);
            lcd.invertLine(24); 
        } else {
            lcd.printString("2. Settings", 0, 3);
        }

        if (menu_index == 2) {
            lcd.printString("3. Help", 0, 4);
            lcd.invertLine(32);   
        } else {
            lcd.printString("3. Help", 0, 4);
        }

        if (menu_index == 3) {
            lcd.printString("4. Achievement", 0, 5);
            lcd.invertLine(40);   
        } else {
            lcd.printString("4. Achievement", 0, 5);
        }
        draw_border();
        lcd.refresh();
    } 
    else if (screen_state == 1) {
        play_screen();
    }
    else if(screen_state == 2){
        setting_screen();
    }
    else if(screen_state == 3){
        instruction_screen();
    }
    else if(screen_state == 4){
        achievement_screen();
    }
    else if(screen_state == 5){
        death_screen();
    }
    else if(screen_state == 6){
        victory_screen();
    }
}

/**
 * Function to display the gameplay screen. 
 * This includes clearing the screen, displaying background elements, the player's character, 
 * and health bar.
 */
void play_screen()
{
    lcd.clear();
    if(role_health>0){
        background_display();
        weapon_act();
        role_display();
        draw_EP_value();
        npc_display(npcs, 24, LCD_WIDTH, LCD_HEIGHT);
        reference_background();
        check_role_state();     
    }
    lcd.refresh();   

}

void role_display() {
    update_role_position_and_direction();  
    check_energy_point_collision();     
    check_heart_collision(); 
    lcd.draw_role(role_x, role_y, facing_direction, current_level);  
    lcd.lev_up_gif(role_x-4,role_y-4);
}

uint8_t weapon_state= 0;
void weapon_act()
{
    if(facing_direction == 'R' || facing_direction == 'U')
        lcd.show_weapon(role_x+ROLE_W/2 + 7,role_y-ROLE_W/3);
    else if(facing_direction =='L')
        lcd.show_weapon(role_x-10,role_y-ROLE_W/3);
}

void update_role_position_and_direction() {
    int direction = get_direction(); 
    
    if ((direction == last_direction) && (direction != -1)) {
        direction_count[direction]++;
    } else {
        if (direction >= 0 && direction < NUM_DIRECTIONS)
            direction_count[direction] = 1;

        if (last_direction >= 0 && last_direction < NUM_DIRECTIONS)
            direction_count[last_direction] = 0;
    }

    if (direction_count[direction] >= STAY_THRESHOLD) {
        direction_count[direction] = 0;

        const int dx[9] = { -1,  -1,  0, 1, 1, 1,  0,  -1 ,0};
        const int dy[9] = { 0,  1,  1,  1,  0, -1, -1, -1 ,0};

        if (direction >= 0 && direction < 8) {
            int new_role_x = role_x + dx[direction];
            int new_role_y = role_y + dy[direction];
            
            // Update role position horizontally
            if (new_role_x >= min_x && new_role_x <= max_x) {
                role_x = new_role_x;
            } else {
                if (dx[direction] == 1 && screen_offset_x < MAP_WIDTH - LCD_WIDTH) {
                    screen_offset_x += 1;
                } else if (dx[direction] == -1 && screen_offset_x > 0) {
                    screen_offset_x -= 1;
                }
            }

            // Update role position vertically
            if (new_role_y >= min_y && new_role_y <= max_y) {
                role_y = new_role_y;
            } else {
                if (dy[direction] == 1 && screen_offset_y < MAP_HEIGHT - LCD_HEIGHT) {
                    screen_offset_y += 1; 
                } else if (dy[direction] == -1 && screen_offset_y > 0) {
                    screen_offset_y -= 1; 
                }
            }

            // Update facing direction
            if (dx[direction] == 1) {
                facing_direction = 'R';
            } else if (dx[direction] == -1) {
                facing_direction = 'L';
            } else if (dy[direction] == -1) {
                facing_direction = 'U';
            } else {
                facing_direction = 'R';
            }
        }
    }

    last_direction = direction;
}

void check_energy_point_collision() {
    for (int i = 0; i < point_num; i++) {
        if (!energy_point_collected[i]) { 
            int role_left = role_x + screen_offset_x;
            int role_right = role_x + screen_offset_x + ROLE_W;
            int role_top = role_y + screen_offset_y;
            int role_bottom = role_y + screen_offset_y + ROLE_H;

            int energy_point_x = energy_point_pos[i][0] + POINT_WIDTH / 2;
            int energy_point_y = energy_point_pos[i][1] + POINT_HEIGHT / 2;

            // Check for collision
            if (role_left <= energy_point_x && energy_point_x <= role_right &&
                role_top <= energy_point_y && energy_point_y <= role_bottom) {
                energy_point_collected[i] = true;  
                current_experience++; 
                check_level_up();
                break; 
            }
        }
    }
}

void reference_background()
{
    int horizontal_offset = screen_offset_x % LCD_WIDTH;  
    int vertical_offset = screen_offset_y % LCD_HEIGHT;  

    int circle_radius = 2;  
    int x_coords[] = {7, 21, 35, 49, 63, 77};  
    int y_coords[] = {6, 18, 30, 42};         

    for (int i = 0; i < 6; i++) {  
        for (int j = 0; j < 4; j++) {
            int x = x_coords[i] - horizontal_offset;
            int y = y_coords[j] - vertical_offset;
            if (y >= 0 && y <= 10) {
                continue;  
            }
            if (x < 0) x += LCD_WIDTH;
            if (y < 0) y += LCD_HEIGHT;
            if (x >= LCD_WIDTH) x -= LCD_WIDTH;
            if (y >= LCD_HEIGHT) y -= LCD_HEIGHT;
            lcd.drawCircle(x, y, circle_radius, FILL_TRANSPARENT);
        }
    }
}

/**
 * Function to display the background elements including barrels and energy points.
 * It checks if each element is within the visible area and then draws it.
 */
void background_display() 
{       
    for (int i = 0; i < sizeof(barrel_pos) / sizeof(barrel_pos[0]); i++) {
        if (barrel_pos[i][0] >= screen_offset_x && barrel_pos[i][0] <= screen_offset_x + LCD_WIDTH && 
            barrel_pos[i][1] >= screen_offset_y && barrel_pos[i][1] <= screen_offset_y + LCD_HEIGHT) {
            lcd.draw_element(barrel_pos[i][0] - screen_offset_x, barrel_pos[i][1] - screen_offset_y, 3); 
        }
    }

    for (int i = 0; i < point_num; i++) {
        if (!energy_point_collected[i] && energy_point_pos[i][0] >= screen_offset_x && 
            energy_point_pos[i][0] <= screen_offset_x + LCD_WIDTH && 
            energy_point_pos[i][1] >= screen_offset_y && 
            energy_point_pos[i][1] <= screen_offset_y + LCD_HEIGHT) {
            lcd.draw_element(energy_point_pos[i][0] - screen_offset_x, energy_point_pos[i][1] - screen_offset_y, 1);  
        }
    }

    for (int i = 0; i < HEART_POINT_COUNT; i++) {
    if (!heart_collected[i] &&
        heart_point_pos[i][0] >= screen_offset_x &&
        heart_point_pos[i][0] <= screen_offset_x + LCD_WIDTH &&
        heart_point_pos[i][1] >= screen_offset_y &&
        heart_point_pos[i][1] <= screen_offset_y + LCD_HEIGHT) {
        lcd.draw_element(heart_point_pos[i][0] - screen_offset_x, heart_point_pos[i][1] - screen_offset_y, 2); 
    }
}
}



/**
 * Function to display the current player's level, experience, and experience required for the next level.
 * It will display the following on two lines:
 * - Line 1: The current level and current experience.
 * - Line 2: The experience required for the next level.
 * 
 * The format is:
 * - Line 1: "Lvl:x EXP:y"
 * - Line 2: "/z" where `z` is the experience required for the next level.
 * 
 * @param None
 * @return None
 */
uint8_t current_level=1,current_experience=1,level_up_threshold=10;
void draw_EP_value() {
    char level_str[10];   
    char exp_str[10]; 
    char level_up_str[10];
    
    snprintf(level_str, sizeof(level_str), "Lv:%d", current_level);

    snprintf(exp_str, sizeof(exp_str), "EXP:%d", current_experience);
    
    snprintf(level_up_str, sizeof(level_up_str), "/%d", level_up_threshold);
    
    lcd.printString(level_str, 0, 0);  
    
    lcd.printString(exp_str, 0 + strlen(level_str)*5 + 8, 0); 
    
    lcd.printString(level_up_str, strlen(level_str)*5 + strlen(exp_str)+35, 0); 
}

void check_level_up() {
    if (current_experience >= level_up_threshold) {
        current_experience = 0;   
        current_level++;              
        level_up_flag = 1;
        music_flag = 5;//play sound

        if (current_level >= 5) {
            //music_flag = 10; 
            screen_state = 6;
        }
    }
}


//////////////////////////////////////////////////////
uint8_t npc_move_flag=0;
int npc_direction = 0;
void move_npc_randomly(NPC &npc, int min_x, int max_x, int min_y, int max_y) {
    if(++npc_move_flag==10)
    {
        npc_move_flag = 0;
        npc_direction=rand() % 8;
        const int dx[8] = { 1,  1,  0, -1, -1, -1,  0,  1 };
        const int dy[8] = { 0,  1,  1,  1,  0, -1, -1, -1 };

        int new_x = npc.x + dx[npc_direction];
        int new_y = npc.y + dy[npc_direction];

        if (new_x >= min_x && new_x <= max_x) {
            npc.x = new_x;  
        }

        if (new_y >= min_y && new_y <= max_y) {
            npc.y = new_y; 
        }
    }
    //lcd.draw_element(npc.x,npc.x,4);
}

void npc_display(NPC npcs[], int num_npcs, int screen_width, int screen_height)
{
    for (int i = 0; i < num_npcs; i++) {
        if (npcs[i].x >= screen_offset_x && npcs[i].x <= screen_offset_x + screen_width &&
            npcs[i].y >= screen_offset_y && npcs[i].y <= screen_offset_y + screen_height) {
            move_npc_randomly(npcs[i], screen_offset_x, screen_offset_x + screen_width, screen_offset_y, screen_offset_y + screen_height);
            if(npcs[i].type == 1)
                lcd.draw_element(npcs[i].x - screen_offset_x, npcs[i].y - screen_offset_y, 4); 
            else if(npcs[i].type == 2)
                lcd.draw_element(npcs[i].x - screen_offset_x, npcs[i].y - screen_offset_y, 5); 
        }
    }
}

void check_role_state() {
    if (role_heat_flag) return;
    if (role_health<1) return;
    int role_left = screen_offset_x+role_x;
    int role_right = screen_offset_x+role_x + ROLE_W;
    int role_top = screen_offset_y+role_y + 5;
    int role_bottom = screen_offset_y+role_y + ROLE_H - 5;

    for (int i = 0; i < 25; i++) {
        int npc_left = npcs[i].x;
        int npc_right = npcs[i].x + NPC_W;
        int npc_top = npcs[i].y;
        int npc_bottom = npcs[i].y + NPC_H;

        if (role_right > npc_left && role_left < npc_right &&
            role_bottom > npc_top && role_top < npc_bottom) {
            led_show_change(role_health,0);
            role_health--;
            if(role_health>0)
            {
                role_heat_flag = 1;
                music_flag =5;
            }
            else if(role_health==0)
            {
                music_flag = 9;
                screen_state = 5;
                //handle_role_death();
            } 
            break; 
        }
    }
}

#define MAX_VOLUME 10
#define MAX_BRIGHTNESS 10
#define MAX_DIFFICULTY 10

int volume_level = 2;    // Adjust this to your desired initial value
int brightness_level = 10; // Adjust this to your desired initial value
int difficulty_level = 2; 
/*
 * Display the settings screen, allowing adjustment of volume, brightness, and difficulty.
 * 
 * - Highlights the currently selected setting with arrows.
 * - Draws progress bars for each setting.
 * - Displays a border around the screen.
 */
void setting_screen() {
    char run_time_str[10];
    snprintf(run_time_str, sizeof(run_time_str), "Time:%d", count_time);

    lcd.clear();
    if(setting_index==0)
        lcd.printString(">Volume<", 20, 0);
    else
        lcd.printString("Volume", 25, 0);

    if(setting_index==1)
        lcd.printString(">Brightness<", 5, 2);
    else
        lcd.printString("Brightness", 10, 2);

    if(setting_index==2)
        lcd.printString(">Difficulty<", 5, 4);
    else
        lcd.printString("Difficulty", 10, 4);;

    int volume_bar_length = (volume_level * (LCD_WIDTH - 10)) / MAX_VOLUME; 
    lcd.drawRect(0, 10, LCD_WIDTH - 1, 5, FILL_TRANSPARENT); 
    lcd.drawRect(1, 11, volume_bar_length, 3, FILL_BLACK); 
    int brightness_bar_length = (brightness_level * (LCD_WIDTH - 10)) / MAX_BRIGHTNESS; 
    lcd.drawRect(0, 26, LCD_WIDTH - 1, 5, FILL_TRANSPARENT); 
    lcd.drawRect(1, 27, brightness_bar_length, 3, FILL_BLACK); 
    int difficulty_bar_length = (difficulty_level * (LCD_WIDTH - 10)) / MAX_DIFFICULTY; 
    lcd.drawRect(0, 42, LCD_WIDTH - 1, 5, FILL_TRANSPARENT);
    lcd.drawRect(1, 43, difficulty_bar_length, 3, FILL_BLACK); 
    lcd.drawRect(0, 0, LCD_WIDTH - 1, LCD_HEIGHT - 1, FILL_TRANSPARENT);  
    int arrow_x_start = 0;  
    int arrow_x_end = 0;  
    int arrow_y_start = 0; 
    int arrow_y_end = 0;    
    lcd.refresh();
}



void draw_border()
{
    lcd.drawLine(0, 0, 83, 0, 1); 
    lcd.drawLine(83, 0, 83, 47, 1);  
    lcd.drawLine(83, 47, 0, 47, 1);  
    lcd.drawLine(0, 47, 0, 0, 1);    
}


void instruction_screen()
{
    lcd.clear();
    if(instruction_index==0)
    {
        lcd.draw_joystick(0,0); 
    }
    else if(instruction_index==1)
    {
        lcd.draw_encoder(0,0);
        lcd.printString("Change Setting", 0, 0);  
    }
    else if(instruction_index==2)
    {
        lcd.draw_key(23,15);
    }

    lcd.drawRect(0, 0, LCD_WIDTH - 1, LCD_HEIGHT - 1, FILL_TRANSPARENT); 
    lcd.refresh();   
}


#define ATTACK_WIDTH 16   
#define ATTACK_HEIGHT 25  
/*
 * Check if any NPCs are within the player's attack range.
 * 
 * The attack area is determined based on the player's current position and facing direction.
 * - If facing right or up, the attack zone is placed to the right of the player.
 * - If facing left, the attack zone is placed to the left.
 * 
 * For each NPC:
 * - Calculate its bounding box (24x24 size).
 * - If the NPC overlaps with the attack zone, mark it as defeated (set position to -1).
 * - Increase experience points and kill count.
 * - Trigger level-up check and play attack sound.
 */
void check_npc_attack_range() {
    int attack_center_x = role_x + screen_offset_x + ROLE_W / 2;
    int attack_center_y = role_y + screen_offset_y + ROLE_H / 2;
    int attack_left, attack_right, attack_top, attack_bottom;

    if (facing_direction == 'R' || facing_direction == 'U') {
        attack_left = attack_center_x + ROLE_W / 2;
        attack_right = attack_left + ATTACK_WIDTH;
        attack_top = attack_center_y - ROLE_H / 2;
        attack_bottom = attack_top + ATTACK_HEIGHT;
    } 
    else if (facing_direction == 'L') {
        attack_right = attack_center_x - ROLE_W / 2;
        attack_left = attack_right - ATTACK_WIDTH;
        attack_top = attack_center_y - ROLE_H / 2;
        attack_bottom = attack_top + ATTACK_HEIGHT;
    }

    for (int i = 0; i < sizeof(npcs) / sizeof(npcs[0]); i++) {
        int npc_left = npcs[i].x;
        int npc_top = npcs[i].y;
        int npc_right = npc_left + 24;  // NPC width
        int npc_bottom = npc_top + 24;  // NPC height

        if (npc_right >= attack_left && npc_left <= attack_right &&
            npc_bottom >= attack_top && npc_top <= attack_bottom) {
            npcs[i].x = -1;
            npcs[i].y = -1;
            current_experience += 5;
            kill_count++;
            music_flag = 7;
            check_level_up();
        }
    }
}

/*
 * Display the achievement screen based on the current achievement index.
 * 
 * - Index 0: Show highest level reached.
 * - Index 1: Show total kill count.
 * - Index 2: Show total play time.
 * 
 * A trophy icon is drawn, corresponding text is displayed, and a border is added.
 */
void achievement_screen()
{
    lcd.clear(); 

    if (achievement_index == 0) {
        lcd.draw_cup(0, 9);  
        lcd.printString("Highest Level", 4, 0); 
        lcd.printString("**5**", 35, 3);   
    }
    else if (achievement_index == 1) {
        lcd.draw_cup(0, 9);  
        lcd.printString("Kill Count", 12, 0);   
        lcd.printString("**23** ", 35, 3); 
        lcd.printString("Enemies", 35, 4);   
    }
    else if (achievement_index == 2) {
        lcd.draw_cup(0, 9);  
        lcd.printString("PlayGame Time", 0, 0);  
        lcd.printString("**5min** ", 35, 3); 
        lcd.printString("Played", 35, 4); 
    }

    lcd.drawRect(0, 0, LCD_WIDTH - 1, LCD_HEIGHT - 1, FILL_TRANSPARENT); 
    lcd.refresh(); 
}


uint8_t kill_count = 0;
void death_screen()
{
    lcd.clear(); 
    lcd.printString("GAME OVER", 15, 1);

    char level_str[20];
    snprintf(level_str, sizeof(level_str), "Level: %d", current_level);
    lcd.printString(level_str, 20, 2); 

    char kill_count_str[20];
    snprintf(kill_count_str, sizeof(kill_count_str), "Kills: %d", kill_count);
    lcd.printString(kill_count_str, 20, 3);  

    lcd.printString("Press R Retry", 3, 5); 

    lcd.printString("Press L Quit", 3, 4);  

    lcd.drawRect(0, 0, LCD_WIDTH - 1, LCD_HEIGHT - 1, FILL_TRANSPARENT); 

    lcd.refresh();
}

NPC npcs[25] = {    
    {157, 203, 1},  
    {31, 289, 1},  
    {178, 105, 1},   
    {263, 248, 1},   
    {305, 228, 1},  
    {453, 408, 1},  
    {588, 432, 1},   
    {712, 197, 1},   
    {229, 396, 1},
    {399, 222, 1},  
    {56, 62, 1},
    {109, 150, 1},
    {212, 336, 1},
    {347, 102, 1},
    {407, 297, 1},
    {553, 180, 1},
    {636, 276, 1},
    {713, 183, 1},
    {329, 41, 1},
    {607, 108, 1},
    {522, 281, 1},
    {317, 415, 1},
    {189, 370, 1},
    {405, 93, 1},
    {273, 475, 1}
};

NPC npcs_init[25] = { 
    {157, 203, 1},  
    {31, 289, 1},  
    {178, 105, 1},   
    {263, 248, 1},   
    {305, 228, 1},  
    {453, 408, 1},  
    {588, 432, 1},   
    {712, 197, 1},   
    {229, 396, 1},
    {399, 222, 1},  
    {56, 62, 1},
    {109, 150, 1},
    {212, 336, 1},
    {347, 102, 1},
    {407, 297, 1},
    {553, 180, 1},
    {636, 276, 1},
    {713, 183, 1},
    {329, 41, 1},
    {607, 108, 1},
    {522, 281, 1},
    {317, 415, 1},
    {189, 370, 1},
    {405, 93, 1},
    {273, 475, 1}
};

void init_npcs_randomly() {
    srand(time(NULL)); 

    for (int i = 0; i < 25; ++i) {
        npcs[i].x = rand() % 840;  
        npcs[i].y = rand() % 480;  
        npcs[i].type = (rand() % 2)+1;    
    }
}


void game_init() {
    role_x = 30; 
    role_y = 15;  
    facing_direction = 'R';  
    role_health = 4;  
    current_level = 1;  
    current_experience = 1;  
    kill_count = 0;  
    for (int i = 0; i < point_num; i++) {
        energy_point_collected[i] = false;  
    }

    screen_offset_x = 0;
    screen_offset_y = 0;
    led_state = 0x0f;
    init_npcs_randomly();
    init_energy_points();
    init_heart_points();
}




uint16_t energy_point_pos[ENERGY_POINT_COUNT][2];

void init_energy_points() {
    for (int i = 0; i < ENERGY_POINT_COUNT; ++i) {
        energy_point_pos[i][0] = rand() % MAP_WIDTH;   
        energy_point_pos[i][1] = rand() % MAP_HEIGHT; 
    }
}

void init_heart_points() {
    for (int i = 0; i < HEART_POINT_COUNT; ++i) {
        heart_point_pos[i][0] = rand() % MAP_WIDTH;
        heart_point_pos[i][1] = rand() % MAP_HEIGHT;
    }
}


void victory_screen()
{
    lcd.clear(); 
    lcd.printString("VICTORY!", 18, 1);

    char level_str[20];
    snprintf(level_str, sizeof(level_str), "Level: %d", current_level);
    lcd.printString(level_str, 20, 2); 

    char kill_count_str[20];
    snprintf(kill_count_str, sizeof(kill_count_str), "Kills: %d", kill_count);
    lcd.printString(kill_count_str, 20, 3);  

    lcd.printString("Press R Retry", 3, 5); 
    lcd.printString("Press L Quit", 3, 4);  

    lcd.drawRect(0, 0, LCD_WIDTH - 1, LCD_HEIGHT - 1, FILL_TRANSPARENT); 
    lcd.refresh();
}

void check_heart_collision() {
    for (int i = 0; i < HEART_POINT_COUNT; i++) {
        if (!heart_collected[i]) {
            int role_left = role_x + screen_offset_x;
            int role_right = role_x + screen_offset_x + ROLE_W;
            int role_top = role_y + screen_offset_y;
            int role_bottom = role_y + screen_offset_y + ROLE_H;

            int heart_x = heart_point_pos[i][0] + POINT_WIDTH / 2;
            int heart_y = heart_point_pos[i][1] + POINT_HEIGHT / 2;

            if (role_left <= heart_x && heart_x <= role_right &&
                role_top <= heart_y && heart_y <= role_bottom) {
                heart_collected[i] = true;
                if (role_health < 4) { 
                    role_health++;
                    led_show_change(role_health,1); 
                    music_flag = 8; 
                }
                break;
            }
        }
    }
}